﻿using System;
using System.Collections.Generic;
using Microsoft.SqlServer.Management.Smo;
using NazTek.Utility;

namespace NazTek.Archive.Control.Entity
{
    /// <summary>
    /// Encapsulates database specific configuration information for archiving.
    /// </summary>
    [Serializable]
    public sealed class DatabaseMetadata
    {
        /// <summary>
        /// Gets/sets Database name.
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// Gets/sets tables to archive.
        /// </summary>
        public List<TableMetadata> TableList { get; set; }

        /// <summary>
        /// Publishes notification.
        /// </summary>
        internal event EventHandler<NoticeEventArgs> Notice;
        /// <summary>
        /// Gets the server within which the database is contained.
        /// </summary>
        internal Server DatabaseServer
        {
            get { return Parent.DatabaseServer; }
        }
        /// <summary>
        /// Gets/sets parent server information.
        /// </summary>
        internal ServerMetadata Parent { get; set; }
        /// <summary>
        /// Executes <see cref="TableMetadata.Archive"/> for each table specified within the database.
        /// </summary>
        /// <param name="parent">Server within which the database is contained.</param>
        internal void Archive(ServerMetadata parent)
        {
            Notify(string.Format("Archiving database: {0}", Name));
            Parent = parent;
            TableList.ForEach(table =>
            {
                Notify(string.Format("Archiving table: [{0}].[{1}].[{2}] (to [{3}].[{1}].[{4}])", 
                    Name, table.Schema, table.Name, table.ArchiveDatabaseName, table.GetArchiveTableName(Name)));
                table.Notice += (sender, eventArgs) => Notify(eventArgs.Message);
                table.Archive(this);
            });
        }

        /// <summary>
        /// Publishes notification, when there are active subscribers.
        /// </summary>
        /// <param name="message">Message to publish.</param>
        private void Notify(string message)
        {
            if (Notice != null)
                Notice(this, new NoticeEventArgs(message));
        }
    }
}